package com.cloudfast.oauth.client;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.oauth2.client.resource.OAuth2AccessDeniedException;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.stereotype.Component;

import com.cloudfast.common.result.ApiResponse;
import com.cloudfast.context.error.ErrorCode;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * oauth 请求 异常处理
 *
 * @author liuyw
 * @date 2022年8月29日
 */
@Component
public class CustomAuthenticationEntryPoint extends OAuth2AuthenticationEntryPoint {

    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException e)
            throws IOException, ServletException {
        response.setHeader("Content-Type", "application/json;charset=utf-8");
        ApiResponse api = null;
        Throwable cause = e.getCause();
        if (cause instanceof OAuth2AccessDeniedException) {
            api = ApiResponse.message(ErrorCode.SCOPE_ERROR);
        } else if (e instanceof InsufficientAuthenticationException || cause instanceof InvalidTokenException) {
            api = ApiResponse.message(ErrorCode.TOKEN_VALID_ERROR);
        } else if (e instanceof BadCredentialsException) {
            api = ApiResponse.message(ErrorCode.CLIENT_ERROR);
        } else if (e instanceof UsernameNotFoundException || cause instanceof UsernameNotFoundException) {
            api = ApiResponse.message(ErrorCode.USERNAME_PASSWORD_ERROR);
        } else {
            response.setStatus(403);
            api = ApiResponse.message(ErrorCode.AUTHORIZATION_ERROR);
        }
        response.setStatus(api.getStatusCodeValue());
        response.getWriter().print(objectMapper.writeValueAsString(api));
        response.getWriter().flush();
    }

}